package com.iqik.base.hash;

import java.util.SortedMap;
import java.util.TreeMap;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 基本的IP hash 映射方式
 */
public class HashDemo {

    /**
     * 计算出每个ip的hash值并除留取模的方式映射到不同的服务器中
     */
    public static void baseHash(String[] args) {
        String[] clients = new String[]{"192.168.3.123", "192.168.1.23", "192.168.4 .2", "192.168.2.255"};
        int server = 4;
        for (String client: clients) {
            int abs = Math.abs(client.hashCode());
            System.out.println(client + " 映射到服务器： " + abs % server);
        }
    }


    public static void consistencyHase() {
        // 1。 把服务器节点IP的hash值对应到hash环上
            // 定义服务器ip
        String[] servers = new String[]{"123.111.0.0", "123.101.3.1", "111.20.35.2", "123.98.26.3"};
        // 可排序map
        SortedMap<Integer, String> hashServerMap = new TreeMap<>();
        int virtaulCount = 3;
        for (String server : servers) {
            int serverHash = Math.abs(server.hashCode());
            hashServerMap.put(serverHash, server);
        }
        // 2。 针对客户端IP求出hash值
        String[] clients = new String[]{"192.168.3.123", "192.168.1.23", "192.168.4.2", "192.168.2.255"};
        for (String client : clients) {
            int clientHash = Math.abs(client.hashCode());
            // 3。 找到能处理该请求的服务器（顺时针）
            SortedMap<Integer, String> integerStringSortedMap = hashServerMap.tailMap(clientHash);
            if (integerStringSortedMap.isEmpty()) {
                integerStringSortedMap = hashServerMap;
            }
            System.out.println("=======>>>客户端：" + client + " 被陆游到服务器： " + hashServerMap.get(integerStringSortedMap.firstKey()));
        }
    }

    public static void consistencyVirtualHase() {
        // 1。 把服务器节点IP的hash值对应到hash环上
        // 定义服务器ip
        String[] servers = new String[]{"123.111.0.0", "123.101.3.1", "111.20.35.2", "123.98.26.3"};
        // 可排序map
        SortedMap<Integer, String> hashServerMap = new TreeMap<>();
        int virtualCount = 3;
        for (String server : servers) {
            int serverHash = Math.abs(server.hashCode());
            hashServerMap.put(serverHash, server);
            // 处理虚拟节点
            for (int i = 0; i < virtualCount; i++) {
                int virtualHash = Math.abs((server + "#" + i).hashCode());
                hashServerMap.put(virtualHash, server + " 虚拟出来的节点" + i);
            }
        }

        // 2。 针对客户端IP求出hash值
        String[] clients = new String[]{"192.168.3.123", "192.168.1.23", "192.168.4.2", "192.168.2.255"};
        for (String client : clients) {
            int clientHash = Math.abs(client.hashCode());
            // 3。 找到能处理该请求的服务器（顺时针）
            SortedMap<Integer, String> integerStringSortedMap = hashServerMap.tailMap(clientHash);
            if (integerStringSortedMap.isEmpty()) {
                integerStringSortedMap = hashServerMap;
            }
            System.out.println("=======>>>客户端：" + client + " 被陆游到服务器： " + hashServerMap.get(integerStringSortedMap.firstKey()));
        }
    }

    public static void main(String[] args) {
//        consistencyVirtualHase();

        System.out.println(1 << 30);

        System.out.println(String.valueOf(Math.abs(Math.pow(2, 30))));
    }
}
